﻿using System;
using System.Collections.Generic;

namespace YJKBuildingProfile.YJKBuildingProfile.Triangulation
{
	internal class TriangleEdge
	{
		public TriangleVertex StartPoint { get; set; }

		public TriangleVertex EndPoint { get; set; }

		public Triangle LeftTriangle { get; set; }

		public Triangle RightTriangle { get; set; }

		public double Perimeter
		{
			get
			{
				return Math.Sqrt(this.EdgeLengthSquare());
			}
		}

		public TriangleEdge()
		{
		}

		public TriangleEdge(TriangleEdge te)
		{
			this.StartPoint = te.StartPoint;
			this.EndPoint = te.EndPoint;
		}

		public TriangleEdge(TriangleVertex startPoint, TriangleVertex endPoint)
		{
			this.StartPoint = startPoint;
			this.EndPoint = endPoint;
		}

		public bool RightOfLine(TriangleVertex p3)
		{
			return (double)((p3.Point.X - this.StartPoint.Point.X) * (this.EndPoint.Point.Y - this.StartPoint.Point.Y) - (p3.Point.Y - this.StartPoint.Point.Y) * (this.EndPoint.Point.X - this.StartPoint.Point.X)) > 0.0;
		}

		public double EdgeLengthSquare()
		{
			double num = (double)this.StartPoint.Point.X;
			double num2 = (double)this.StartPoint.Point.Y;
			double num3 = (double)this.EndPoint.Point.X;
			double num4 = (double)this.EndPoint.Point.Y;
			return (num - num3) * (num - num3) + (num2 - num4) * (num2 - num4);
		}

		public static double LengthSquare(TriangleVertex point1, TriangleVertex point2)
		{
			double num = (double)point1.Point.X;
			double num2 = (double)point1.Point.Y;
			double num3 = (double)point2.Point.X;
			double num4 = (double)point2.Point.Y;
			return (num - num3) * (num - num3) + (num2 - num4) * (num2 - num4);
		}

		public double CosValue(TriangleVertex point3)
		{
			double num = TriangleEdge.LengthSquare(this.StartPoint, point3);
			double num2 = TriangleEdge.LengthSquare(this.EndPoint, point3);
			double num3 = TriangleEdge.LengthSquare(this.StartPoint, this.EndPoint);
			return (num + num2 - num3) / (2.0 * Math.Sqrt(num) * Math.Sqrt(num2));
		}

		public static int GetPointID(TriangleEdge edge, List<TriangleVertex> triPoint)
		{
			double num = 1.0;
			int result = 0;
			foreach (TriangleVertex triangleVertex in triPoint)
			{
				if (edge.RightOfLine(triangleVertex) && edge.CosValue(triangleVertex) < num)
				{
					result = triangleVertex.ID;
					num = edge.CosValue(triangleVertex);
				}
			}
			return result;
		}

		public static TriangleEdge FindSameEdge(List<TriangleEdge> listEdge, TriangleEdge edge)
		{
			foreach (TriangleEdge triangleEdge in listEdge)
			{
				if (triangleEdge.StartPoint == edge.StartPoint && triangleEdge.EndPoint == edge.EndPoint)
				{
					return triangleEdge;
				}
			}
			return null;
		}

		public static TriangleVertex GetBestPoint(TriangleEdge edge, List<TriangleVertex> triPoint)
		{
			if (TriangleEdge.GetPointID(edge, triPoint) == 0)
			{
				return null;
			}
			return triPoint[TriangleEdge.GetPointID(edge, triPoint) - 1];
		}

		public static TriangleEdge FindOppsiteEdge(List<TriangleEdge> listEdge, TriangleEdge edge)
		{
			foreach (TriangleEdge triangleEdge in listEdge)
			{
				if (triangleEdge.StartPoint == edge.EndPoint && triangleEdge.EndPoint == edge.StartPoint)
				{
					return triangleEdge;
				}
			}
			return null;
		}

		public static void GetUniqueEdges(ref List<TriangleEdge> edges)
		{
			List<TriangleEdge> list = new List<TriangleEdge>();
			foreach (TriangleEdge edge in edges)
			{
				TriangleEdge triangleEdge = TriangleEdge.FindOppsiteEdge(edges, edge);
				if (triangleEdge != null && TriangleEdge.FindOppsiteEdge(list, triangleEdge) == null)
				{
					list.Add(triangleEdge);
				}
			}
			foreach (TriangleEdge item in list)
			{
				edges.Remove(item);
			}
		}
	}
}
